/**
 * @Author ZhangGJ
 * @Date 2021/11/14 09:49
 */
#include "currency.h"
#include "../../exception/exception.h"

Currency::Currency(SignType theSign, unsigned long theDollars, unsigned int theCents)
{
    setValue(theSign, theDollars, theCents);
}

void Currency::setValue(SignType theSign, unsigned long theDollars, unsigned int theCents)
{
    if (theCents > 99)
    {
        throw illegalParameterValue("Cents should be < 100");
    }
    sign = theSign;
    dollars = theDollars;
    cents = theCents;
}

void Currency::setValue(double theAmount)
{
    if (theAmount < 0)
    {
        sign = SignType::minus;
        theAmount = -theAmount;
    }
    else
    {
        sign = SignType::plus;
    }
    dollars = (unsigned long) theAmount;
    cents = (unsigned int) ((theAmount + 0.001 - dollars) * 100);
}

Currency Currency::add(const Currency &x) const
{
    long a1, a2, a3;
    Currency result;
    a1 = dollars * 100 + cents;
    if (sign == SignType::minus)
    {
        a1 = -a1;
    }
    a2 = x.dollars * 100 + x.cents;
    if (x.sign == SignType::minus)
    {
        a2 = -a2;
    }
    a3 = a1 + a2;
    if (a3 < 0)
    {
        result.sign = SignType::minus;
        a3 = -a3;
    }
    else
    {
        result.sign = SignType::plus;
    }
    result.dollars = a3 / 100;
    result.cents = a3 - result.dollars * 100;
    return result;
}

Currency &Currency::increment(const Currency &x)
{
    *this = add(x);
    return *this;
}

void Currency::output() const
{
    if (sign == SignType::minus)
    {
        std::cout << '-';
    }
    std::cout << '$' << dollars << '.';
    if (cents < 10)
    {
        std::cout << '0';
    }
    std::cout << cents;
}

int main()
{
    Currency g, h(SignType::plus, 3, 50), i, j;
    g.setValue(SignType::minus, 2, 25);
    i.setValue(-6.45);
    j = h.add(g);
    h.output();
    std::cout << " + ";
    g.output();
    std::cout << " = ";
    j.output();
    std::cout << std::endl;

    j = i.add(g).add(h);
    j = i.increment(g).add(h);
    std::cout << "Attempting to initialize with cents = 152" << std::endl;
    try
    {
        i.setValue(SignType::plus, 3, 152);
    }
    catch (illegalParameterValue &e)
    {
        std::cout << "Caught thrown exception" << std::endl;
        e.outputMessage();
    }
    return 0;
}
